import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:logger/logger.dart';
import 'package:super_sliver_list/super_sliver_list.dart';

import '../../im/page/bloc/MessageListCubit.dart';
import '../../im/page/sub/MessageRefInfoPage.dart';
import '../../im/page/sub/UserInfoPage.dart';
import '../../im/page/view/component/UserIconView.dart';
import '../../im/page/view/component/pane/MessagePane.dart';
import '../../im/pojo/ImPojo.dart';
import '../../im/util/HexColor.dart';
import '../../im/util/ImConstant.dart';
import '../../im/util/ImSingleton.dart';

class ListViewPage extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => ListViewState();
}

class ListViewState extends State<ListViewPage> {
  var dataList = <int>[];
  final _scrollController = ScrollController();
  final _listController = ListController();
  var firstIndex = 0;
  var lastIndex = 20;

  @override
  void initState() {
    super.initState();
    for (var i = 0; i < 20; i++) {
      dataList.add(i);
    }

    _scrollController.addListener(() {
      print('atEdget: ${_scrollController.position.atEdge}, pixels: ${_scrollController.position.pixels}');
      if (_scrollController.position.atEdge &&
          _scrollController.position.pixels != 0) {
        loadMoreData();
      } else if (_scrollController.position.atEdge && _scrollController.position.pixels == 0) {
        loadOldData();
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: buildAppbar(),
      body: SuperListView.builder(
        scrollDirection: Axis.vertical,
        controller: _scrollController,
        listController: _listController,
        itemBuilder: (BuildContext context, int index) {
          var message =  ImMessage(fromUserId: 'demo001', messageType: ImMessageType.Text, content: dataList[index].toString());
          message.fromImUser = ImUser('demo001');
          var wrapMessage = toWrapImMessage(message);
          return ListTile(
            title: MessageItemView(wrapMessage: wrapMessage),
          );
        },
        itemCount: dataList.length,
      ),
    );
  }

  AppBar buildAppbar() {
    return AppBar();
  }

  void loadMoreData() {
    Future.delayed(const Duration(milliseconds: 1500), (){
      changeMoreData();
    });
  }

  changeMoreData() {
    var selectIndex = dataList.length;
    setState(() {
      for (var i=lastIndex; i<lastIndex + 10; i++) {
        dataList.add(i);
      }
      if (dataList.length > 100) {
        dataList.removeRange(0, 20);
        firstIndex+=20;
        selectIndex-=20;
      }
      lastIndex+=10;

    });
    WidgetsBinding.instance.addPostFrameCallback((_) async {
      _listController.jumpToItem(index: selectIndex, scrollController: _scrollController, alignment: 1);
    });
  }

  void loadOldData() {
    Future.delayed(const Duration(milliseconds: 1500), (){
      changeOldData();
    });

  }

  changeOldData() {
    setState(() {
      for (var i=firstIndex; i>firstIndex-10; i--) {
        dataList.insert(0, i);
      }
      if (dataList.length > 100) {
        dataList.removeRange(dataList.length-20, dataList.length);
        lastIndex-=20;
      }
      firstIndex-=10;
    });
    WidgetsBinding.instance.addPostFrameCallback((_) async {
      _listController.jumpToItem(index: 10, scrollController: _scrollController, alignment: 0);
    });
  }

  @override
  void dispose() {
    super.dispose();
    _scrollController.dispose();
  }
}


class MessageItemView extends StatelessWidget {
  final WrapImMessage wrapMessage;
  final _logger = Logger();

  MessageItemView({required this.wrapMessage, super.key});

  @override
  Widget build(BuildContext context) {
    Widget messagePane = wrapMessage.message.currentUserId == wrapMessage.message.fromUserId
        ? _buildRightMessagePane(context)
        : _buildLeftMessagePane(context);

    return Container(
        color: Colors.transparent,
        padding: const EdgeInsets.only(top: 5, bottom: 5),
        child: messagePane
    );
  }

  Widget _buildRightMessagePane(BuildContext context) {
    return Row(
      mainAxisSize: MainAxisSize.min,
      crossAxisAlignment: CrossAxisAlignment.start,
      mainAxisAlignment: MainAxisAlignment.end,
      children: [
        const Expanded(child: Text('')),
        _buildRightContent(context),
        if (wrapMessage.message.messageType != ImMessageType.Image) _buildRightPath(),
        _buildMessageTitle(context),
      ],
    );
  }

  Widget _buildLeftMessagePane(BuildContext context) {
    return Row(
      mainAxisSize: MainAxisSize.min,
      crossAxisAlignment: CrossAxisAlignment.start,
      mainAxisAlignment: MainAxisAlignment.start,
      children: [
        const SizedBox(width: 10,),
        _buildMessageTitle(context),
        if (wrapMessage.message.messageType != ImMessageType.Image) _buildLeftPath(),
        _buildLeftContent(context),
        const Expanded(child: Text('')),
      ],
    );
  }

  Widget _buildMessageTitle(BuildContext context) {
    return GestureDetector(
      child: ClipRRect(
        borderRadius: const BorderRadius.all(Radius.circular(30)),
        child: UserIconView(user: wrapMessage.message.fromImUser!, iconSize: ImConstant.IM_USER_ICON_SIZE - 15,),
      ),
      onTap: () {
        Navigator.push(context, MaterialPageRoute(builder: (BuildContext context) {
          return UserInfoPage(user: wrapMessage.message.fromImUser!);
        }));
      },
    );
  }

  Widget _buildLeftContent(BuildContext context) {
    String? groupCode = wrapMessage.message.groupCode;
    if (groupCode != null) {
      return Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Padding(
            padding: const EdgeInsets.only(bottom: 5),
            child: Text(
              wrapMessage.message.fromGroupUser?.userName ?? (wrapMessage.message.fromImUser?.userName ??''),
              style: const TextStyle(fontSize: ImConstant.IM_SMALL_SIZE),
            ),
          ),
          _buildLeftContentItem(context),
          if (wrapMessage.message.refMessages != null)
            Padding(
              padding: const EdgeInsets.only(top: 5),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: wrapMessage.message.refMessages!.map((refMessage) => _buildRefLeftPane(context, refMessage))
                    .toList(),
              ),
            ),
        ],
      );
    } else {
      if (wrapMessage.message.refMessages != null) {
        var result = <Widget>[];
        result.add(_buildLeftContentItem(context));
        var refPanes = wrapMessage.message.refMessages!.map((refMessage) => _buildRefLeftPane(context, refMessage)).toList();
        result.addAll(refPanes);
        return Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: result,
        );
      } else {
        return _buildLeftContentItem(context);
      }
    }
  }

  Widget _buildRightContent(BuildContext context) {
    String? groupCode = wrapMessage.message.groupCode;
    if (groupCode != null) {
      return Column(
        crossAxisAlignment: CrossAxisAlignment.end,
        children: <Widget>[
          Padding(
            padding: const EdgeInsets.only(bottom: 5),
            child: Text(
              wrapMessage.message.fromGroupUser?.userName ?? '',
              style: const TextStyle(fontSize: ImConstant.IM_SMALL_SIZE),
            ),
          ),
          _buildRightContentItem(context),
          if (wrapMessage.message.refMessages != null)
            Padding(
              padding: const EdgeInsets.only(top: 5),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.end,
                children: wrapMessage.message.refMessages!.map((refMessage) => _buildRefRightPane(context, refMessage)).toList(),
              ),
            ),
        ],
      );
    } else {
      if (wrapMessage.message.refMessages != null) {
        var result = <Widget>[];
        result.add(_buildRightContentItem(context));
        var refPanes = wrapMessage.message.refMessages!.map((refMessage) => _buildRefRightPane(context, refMessage)).toList();
        result.addAll(refPanes);
        return Column(
          crossAxisAlignment: CrossAxisAlignment.end,
          children: result,
        );
      } else {
        return _buildRightContentItem(context);
      }
    }
  }

  Widget _buildLeftContentItem(BuildContext context) {
    return Row(
      crossAxisAlignment: CrossAxisAlignment.end,
      children: [
        ConstrainedBox(
            constraints: const BoxConstraints(maxWidth: ImConstant.MESSAGE_MAX_WIDTH),
            // child: MessagePaneEnum.getByMessageType(wrapMessage.message.messageType).executor(wrapMessage.message),
            child: Text(wrapMessage.content)
        ),
        _buildMessageStatus(context),
      ],
    );
  }

  Widget _buildRightContentItem(BuildContext context) {
    return Row(
      crossAxisAlignment: CrossAxisAlignment.end,
      children: [
        _buildMessageStatus(context),
        ConstrainedBox(
            constraints: const BoxConstraints(maxWidth: ImConstant.MESSAGE_MAX_WIDTH),
            // child: MessagePaneEnum.getByMessageType(wrapMessage.message.messageType).executor(wrapMessage.message),
            child: Container(
              color: Colors.green,
              margin: const EdgeInsets.only(left: 10),
              padding: const EdgeInsets.only(top: 5, bottom: 5, left: 10, right: 10),
              child: Text(wrapMessage.content),
            )
        )
      ],
    );
  }

  Widget _buildMessageStatus(BuildContext context) {
    if (wrapMessage.status == WrapImMessageStatus.uploading) {
      return Padding(
        padding: const EdgeInsets.only(left: 5, right: 5),
        child: SizedBox(height: 15, width: 15, child: CircularProgressIndicator(value: wrapMessage.uploadProgress),),
      );
    }
    if (wrapMessage.status == WrapImMessageStatus.downloading) {
      return Padding(
        padding: const EdgeInsets.only(left: 5, right: 5),
        child: SizedBox(height: 15, width: 15, child: CircularProgressIndicator(value: wrapMessage.downloadProgress),),
      );
    }
    if (wrapMessage.statusFile == '') {
      return const Text('');
    }
    return Padding(
      padding: const EdgeInsets.only(left: 5, right: 5, top: 20),
      child: GestureDetector(
        child: Image(
          image: AssetImage(wrapMessage.statusFile),
          height: 12,
          width: 12,
        ),
        onTap: () {
        },
      ),
    );
  }

  Widget _buildLeftPath() {
    String? groupCode = wrapMessage.message.groupCode;
    return Padding(
      padding: EdgeInsets.only(left: 2, top: groupCode != null ? 27 : 6),
      child: CustomPaint(
        painter: LeftPath(),
        size: const Size(5, 10),
      ),
    );
  }

  Widget _buildRightPath() {
    String? groupCode = wrapMessage.message.groupCode;
    return Padding(
      padding: EdgeInsets.only(right: 2, top: groupCode != null ? 27 : 6),
      child: CustomPaint(
        painter: RightPath(),
        size: const Size(5, 10),
      ),
    );
  }

  Widget _buildRefLeftPane(BuildContext context, ImMessage refMessage) {
    return GestureDetector(
      onTap: () {
        Navigator.of(context).push(MaterialPageRoute(builder: (context){
          return MessageRefInfoPage(message: refMessage);
        }));
      },
      child: Container(
          alignment: Alignment.topLeft,
          padding: const EdgeInsets.only(top: 6, right: 5, bottom: 6, left: 6),
          margin: const EdgeInsets.only(top: 5),
          decoration: ShapeDecoration(
            color: Colors.grey.shade300,
            shape:
            const RoundedRectangleBorder(side: BorderSide.none, borderRadius: BorderRadius.all(Radius.circular(5))),
          ),
          child: ConstrainedBox(
              constraints: const BoxConstraints(maxWidth: 250),
              child: MessageRefPane(
                message: refMessage,
                param: MessageRefParam(maxLines: 1, hasPrefix: true),
              ))
      ),
    );
  }

  Widget _buildRefRightPane(BuildContext context, ImMessage refMessage) {
    return GestureDetector(
      onTap: () {
        Navigator.of(context).push(MaterialPageRoute(builder: (context){
          return MessageRefInfoPage(message: refMessage);
        }));
      },
      child: Container(
          alignment: Alignment.topRight,
          padding: const EdgeInsets.only(top: 6, right: 5, bottom: 6, left: 6),
          margin: const EdgeInsets.only(top: 5),
          decoration: ShapeDecoration(
            color: Colors.grey.shade300,
            shape: const RoundedRectangleBorder(side: BorderSide.none, borderRadius: BorderRadius.all(Radius.circular(5))),
          ),
          child: ConstrainedBox(
              constraints: const BoxConstraints(maxWidth: ImConstant.MESSAGE_MAX_WIDTH),
              // child: MessagePaneEnum.getByMessageType(wrapMessage.message.messageType).executor(wrapMessage.message),
              child: MessageRefPane(
                message: refMessage,
                param: MessageRefParam(maxLines: 1, hasPrefix: true),
              ))
      ),
    );
  }
}

class LeftPath extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    Paint paint = Paint()
      ..color = Colors.white
      ..style = PaintingStyle.fill
      ..strokeWidth = 1;

    Path path = Path();
    path
      ..moveTo(0, 5)
      ..lineTo(5, 0)
      ..lineTo(5, 10)
      ..close();
    canvas.drawPath(path, paint);
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) => true;
}

class RightPath extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    Paint paint = Paint()
      ..color = HexColor.fromHex("#95EC69")
      ..style = PaintingStyle.fill
      ..strokeWidth = 1;

    Path path = Path();
    path
      ..moveTo(0, 0)
      ..lineTo(5, 5)
      ..lineTo(0, 10)
      ..close();
    // path.transform(Matrix4.translationValues(5, 2, 0))
    canvas.drawPath(path, paint);
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) => true;
}
